package tuanda.soict.firstsun.PresentationPackage;

import java.util.ArrayList;

import tuanda.soict.firstsun.BuildingPackage.Building;
import tuanda.soict.firstsun.DataPackage.ArmyDataSet;
import tuanda.soict.firstsun.DataPackage.AttributeList;
import tuanda.soict.firstsun.DataPackage.BuildingDataSet;
import tuanda.soict.firstsun.DataPackage.CommonConstants;
import tuanda.soict.firstsun.DataPackage.EnvironmentDataSet;
import tuanda.soict.firstsun.DataPackage.GroupDataStructure;
import tuanda.soict.firstsun.LogicPackage.AI_Part;
import tuanda.soict.firstsun.LogicPackage.BattleMap;
import tuanda.soict.firstsun.LogicPackage.Group;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;

public class ScenarioInitializer implements CommonConstants, GeneralConstants,
		AttributeList {

	private int[] tileID;
	private TextureRegion[][] icon;
	private int[] creatures;
	private TextureRegion[][] creatureTexture;
	private TextureRegion[][] buildingTexture;
	private TextureRegion[][] menu;
	private TextureRegion[][] selection;
	private TextureRegion[][] statusIcon;
	private TextureRegion[] attackAnimation;
	private TextureRegion[] levelUpAnimation;
	private TextureRegion[][] numbers;

	public ScenarioInitializer() {
		initializeCreature();
		initializeMenu();
	}

	public void initializeCreature() {
		creatures = new int[DEFAULT_MAX_GROUP];
		creatureTexture = new TextureRegion[DEFAULT_MAX_GROUP][];
		buildingTexture = new TextureRegion[DEFAULT_MAX_GROUP + 1][];
		for (int i = 0; i < creatures.length; i++) {
			creatures[i] = GROUP_NOT_EXIST;
		}
	}

	public void initializeMenu() {
		menu = TextureRegion.split(
				new Texture(Gdx.files.internal("Images/Menu.png")), 64, 128);
		selection = TextureRegion
				.split(new Texture(Gdx.files.internal("Images/Selection.png")),
						64, 64);
		icon = TextureRegion.split(
				new Texture(Gdx.files.internal("Images/Icon.png")), 64, 64);
		statusIcon = TextureRegion.split(
				new Texture(Gdx.files.internal("Images/Status.png")), 32, 32);
		TextureRegion[][] temp = TextureRegion.split(new Texture(
				"Images/Attack.png"), 128, 128);
		int index = 0;
		attackAnimation = new TextureRegion[16];
		for (int i = 0; i < temp.length; i++) {
			for (int j = 0; j < temp[0].length; j++) {
				attackAnimation[index++] = temp[i][j];
			}
		}
		index = 0;
		levelUpAnimation = new TextureRegion[32];
		TextureRegion[][] tempLevelUp = TextureRegion.split(new Texture(
				"Images/LevelUp.png"), 128, 128);
		for (int i = 0; i < tempLevelUp.length; i++)
			for (int j = 0; j < tempLevelUp[0].length; j++) {
				levelUpAnimation[index++] = tempLevelUp[i][j];
			}
		index = 0;
		TextureRegion[][] tempNumbers = TextureRegion.split(new Texture(
				"Images/Numbers.png"), 16, 16);
		numbers = new TextureRegion[DEFAULT_MAX_GROUP][10];
		for (int i = 0; i < DEFAULT_MAX_GROUP; i++) {
			index = 0;
			for (int j = 0; j < 10; j++) {
				numbers[i][index] = tempNumbers[i][j];
				index++;
			}
		}
	}

	public ImageButton getElement(int index) {
		switch (index) {
		case WATER_ATTRIBUTE:
			return new ImageButton(getIcon(2, 4), getIcon(4, 4));
		case FIRE_ATTRIBUTE:
			return new ImageButton(getIcon(2, 5), getIcon(4, 5));
		case AIR_ATTRIBUTE:
			return new ImageButton(getIcon(3, 4), getIcon(5, 4));
		case EARTH_ATTRIBUTE:
			return new ImageButton(getIcon(3, 5), getIcon(5, 5));
		case LIGHT_ATTRIBUTE:
			return new ImageButton(getIcon(5, 6), getIcon(6, 6));
		case DARK_ATTRIBUTE:
			return new ImageButton(getIcon(6, 4), getIcon(6, 5));
		default:
			return new ImageButton(getIcon(2, 4), getIcon(4, 4));
		}
	}

	public TextureRegion getNumbers(int index, int groupID) {
		if (index > -1 && index < 10) {
			if (groupID > -1 && groupID < DEFAULT_MAX_GROUP) {
				return numbers[groupID][index];
			} else {
				return null;
			}

		} else {
			return null;
		}
	}

	public TextureRegion getAttackAnimation(int i) {
		if (i > -1 && i < attackAnimation.length)
			return attackAnimation[i];
		else
			return null;
	}

	public TextureRegion getLevelUpAnimation(int i) {
		if (i > -1 && i < levelUpAnimation.length)
			return levelUpAnimation[i];
		else
			return null;
	}

	public Texture getMenuTile(int groupID) {
		if (groupID > -1 && groupID < DEFAULT_MAX_GROUP) {
			return this.menu[0][groupID].getTexture();
		} else {
			return this.menu[0][0].getTexture();
		}
	}

	public TextureRegion getStatusIcon(int i, int j) {
		return statusIcon[i][j];
	}

	public TextureRegion getIcon(int i, int j) {
		return icon[i][j];
	}

	public TextureRegion getSelectionIcon(int index, int groupID) {
		return selection[index][groupID];
	}

	public TextureRegion[][] getCreatureTextureRegion() {
		return this.creatureTexture;
	}

	public TextureRegion[][] getBuildingTextureRegion() {
		return this.buildingTexture;
	}

	public void parseTileSetData(String path) {
		String plain = (Gdx.files.internal(path)).readString();
		int i = plain.indexOf(";");
		int k = plain.indexOf(":");
		tileID = new int[Integer.parseInt((plain.substring(k + 1, i)))];
		i = plain.indexOf(";", i + 1);
		k = plain.indexOf(":", k + 1);
		int j = 0;
		while (i != -1) {
			tileID[j] = Integer.parseInt(plain.substring(k + 1, i));
			j++;
			i = plain.indexOf(";", i + 1);
			k = plain.indexOf(":", k + 1);
		}
	}

	public BattleMap parseTiledMapData(TiledMapHelper tiledMapHelper) {
		TiledMap map = tiledMapHelper.getMap();
		EnvironmentDataSet env = EnvironmentDataSet.ROAD, temp;
		int cols = map.layers.get(0).getWidth();
		int rows = map.layers.get(0).getHeight();
		BattleMap battleMap = new BattleMap(rows, cols);
		int i, j, id;
		for (j = 0; j < rows; j++) {
			for (i = 0; i < cols; i++) {
				id = map.layers.get(1).tiles[j][i] - 1;
				if (id != -1) {
					temp = env.getEnvironmentData(tileID[id]);
					battleMap.setEnvironment(i, j, temp.getName(),
							temp.getDefense(), temp.getObstaclePoint(),
							temp.getCategory());
				} else {
					id = map.layers.get(0).tiles[j][i] - 1;
					temp = env.getEnvironmentData(tileID[id]);
					battleMap.setEnvironment(i, j, temp.getName(),
							temp.getDefense(), temp.getObstaclePoint(),
							temp.getCategory());
				}
				// System.out.printf("%10s", temp.getName());
			}
			// System.out.println();
		}
		return battleMap;
	}

	public AI_Part parseScenarioData(String path,
			TiledMapHelper tiledMapHelper, boolean isCampaign,
			GroupDataStructure groupDataStructure) {
		if (isCampaign == true) {
			String plain = (Gdx.files.internal(path)).readString();
			int i = plain.indexOf(":");
			int k = plain.indexOf(";");
			int size = Integer.parseInt(plain.substring(i + 1, k));
			Group[] group = new Group[size];
			BattleMap battleMap = parseTiledMapData(tiledMapHelper);
			int[] playerType = new int[group.length];
			for (int u = 0; u < playerType.length; u++) {
				i = plain.indexOf(":", i + 1);
				k = plain.indexOf(";", k + 1);
				playerType[u] = Integer.parseInt(plain.substring(i + 1, k));
			}
			ArrayList<Building> neutral;
			i = plain.indexOf(":", i + 1);
			k = plain.indexOf(";", k + 1);
			int numberNeutral = Integer.parseInt(plain.substring(i + 1, k));
			neutral = new ArrayList<Building>(numberNeutral);
			AI_Part ai_Part = new AI_Part(battleMap, group, 0, playerType,
					neutral);

			int j = -1;
			int id, l, m, x, y;
			String name;
			ArmyDataSet army;
			BuildingDataSet build;
			int side, gold, type;

			for (int index = 0; index < numberNeutral; index++) {
				i = plain.indexOf(":", i + 1);
				k = plain.indexOf(";", k + 1);
				id = Integer.parseInt(plain.substring(i + 1, k));
				i = plain.indexOf(",", i + 1);
				x = Integer.parseInt(plain.substring(k + 1, i));
				k = plain.indexOf(";", k + 1);
				y = Integer.parseInt(plain.substring(i + 1, k));
				build = BuildingDataSet.TOWN.getBuildingData(id);
				ai_Part.addNeutralBuildingToMap(build, x, y);
			}

			i = plain.indexOf(":", i + 1);
			while (i != -1) {
				if (plain.substring(k + 1, i).trim()
						.equalsIgnoreCase("GroupName") == true) {
					k = plain.indexOf(";", k + 1);
					name = plain.substring(i + 1, k);
					i = plain.indexOf(":", i + 1);
					k = plain.indexOf(";", k + 1);
					side = Integer.parseInt(plain.substring(i + 1, k));
					i = plain.indexOf(":", i + 1);
					k = plain.indexOf(";", k + 1);
					gold = Integer.parseInt(plain.substring(i + 1, k));
					i = plain.indexOf(":", i + 1);
					k = plain.indexOf(";", k + 1);
					type = Integer.parseInt(plain.substring(i + 1, k));
					j++;
					group[j] = new Group(name, side, j, gold, type);
					creatures[j] = type;
					// System.out.println("|" + name + "|" + side + "|" + j +
					// "|"+gold+"|"+type+"|");
					// System.out.println();
				} else {
					if (plain.substring(k + 1, i).trim()
							.equalsIgnoreCase("Army") == true) {
						k = plain.indexOf(";", k + 1);
						l = Integer.parseInt(plain.substring(i + 1, k));
						for (m = 0; m < l; m++) {
							i = plain.indexOf(":", i + 1);
							k = plain.indexOf(";", k + 1);
							id = Integer.parseInt(plain.substring(i + 1, k));
							i = plain.indexOf(",", i + 1);
							x = Integer.parseInt(plain.substring(k + 1, i));
							k = plain.indexOf(";", k + 1);
							y = Integer.parseInt(plain.substring(i + 1, k));
							army = ArmyDataSet.SOLDIER.getArmyData(id);
							ai_Part.addInitialArmy(army, j, x, y);
							// System.out.println("|" + id + "|" + x + "|" + y +
							// "|");
						}
						// System.out.println();
					} else {// (plain.substring(k + 1,
							// i).trim().equalsIgnoreCase("Building") == true)
						k = plain.indexOf(";", k + 1);
						l = Integer.parseInt(plain.substring(i + 1, k));
						for (m = 0; m < l; m++) {
							i = plain.indexOf(":", i + 1);
							k = plain.indexOf(";", k + 1);
							id = Integer.parseInt(plain.substring(i + 1, k));
							i = plain.indexOf(",", i + 1);
							x = Integer.parseInt(plain.substring(k + 1, i));
							k = plain.indexOf(";", k + 1);
							y = Integer.parseInt(plain.substring(i + 1, k));
							build = BuildingDataSet.TOWN.getBuildingData(id);
							ai_Part.addBuilding(build, j, x, y);
							// System.out.println("|" + id + "|" + x + "|" + y +
							// "|");
						}
						// System.out.println();
					}
				}
				i = plain.indexOf(":", i + 1);
			}
			ai_Part.initialzeEnemyHQ();
			ai_Part.initializeArmyDefense();
			return ai_Part;
		} else {
			String plain = (Gdx.files.internal(path)).readString();
			int i = plain.indexOf(":");
			int k = plain.indexOf(";");
			int size = Integer.parseInt(plain.substring(i + 1, k));

			String[] groupName = groupDataStructure.getGroupName();
			int[] tempType = groupDataStructure.getPlayerType();
			int[] groupIncome = groupDataStructure.getGroupIncome();
			int[] groupType = groupDataStructure.getGroupType();
			int[] groupSide = groupDataStructure.getGroupSide();

			int[] playerType;
			int groupSize = 0;
			for (int index = 0; index < groupName.length; index++) {
				if (groupName[index] != null) {
					groupSize++;
				}
			}

			playerType = new int[groupSize];

			int tempIndex = 0;
			for (int index = 0; index < groupName.length; index++) {
				if (groupName[index] != null) {
					playerType[tempIndex] = tempType[index];
					tempIndex++;
				}
			}

			Group[] group = new Group[groupSize];
			BattleMap battleMap = parseTiledMapData(tiledMapHelper);

			ArrayList<Building> neutral = new ArrayList<Building>();

			i = plain.indexOf(":", i + 1);
			k = plain.indexOf(";", k + 1);
			int numberNeutral = Integer.parseInt(plain.substring(i + 1, k));
			int id, x, y;
			BuildingDataSet build;

			AI_Part ai_Part = new AI_Part(battleMap, group, 0, playerType,
					neutral);

			for (int index = 0; index < numberNeutral; index++) {
				i = plain.indexOf(":", i + 1);
				k = plain.indexOf(";", k + 1);
				id = Integer.parseInt(plain.substring(i + 1, k));
				i = plain.indexOf(",", i + 1);
				x = Integer.parseInt(plain.substring(k + 1, i));
				k = plain.indexOf(";", k + 1);
				y = Integer.parseInt(plain.substring(i + 1, k));
				build = BuildingDataSet.TOWN.getBuildingData(id);
				ai_Part.addNeutralBuildingToMap(build, x, y);
			}

			int numberBuilding;
			int numberGroup = -1;
			for (int m = 0; m < size; m++) {
				i = plain.indexOf(":", i + 1);
				k = plain.indexOf(";", k + 1);
				numberBuilding = Integer.parseInt(plain.substring(i + 1, k));

				if (groupName[m] != null) {
					numberGroup++;
					group[numberGroup] = new Group(groupName[m], groupSide[m],
							numberGroup, groupIncome[m], groupType[m]);
					creatures[numberGroup] = groupType[m];

					for (int n = 0; n < numberBuilding; n++) {
						i = plain.indexOf(":", i + 1);
						k = plain.indexOf(";", k + 1);
						id = Integer.parseInt(plain.substring(i + 1, k));
						i = plain.indexOf(",", i + 1);
						x = Integer.parseInt(plain.substring(k + 1, i));
						k = plain.indexOf(";", k + 1);
						y = Integer.parseInt(plain.substring(i + 1, k));
						build = BuildingDataSet.TOWN.getBuildingData(id);
						ai_Part.addBuilding(build, numberGroup, x, y);
					}
				} else {
					for (int index = 0; index < numberBuilding; index++) {
						i = plain.indexOf(":", i + 1);
						k = plain.indexOf(";", k + 1);
						id = Integer.parseInt(plain.substring(i + 1, k));
						i = plain.indexOf(",", i + 1);
						x = Integer.parseInt(plain.substring(k + 1, i));
						k = plain.indexOf(";", k + 1);
						y = Integer.parseInt(plain.substring(i + 1, k));
					}
				}
			}

			ai_Part.initialzeEnemyHQ();
			ai_Part.initializeArmyDefense();
			return ai_Part;
		}
	}

	public void createCreatureTile() {
		for (int i = 0; i < creatures.length; i++) {
			if (creatures[i] != GROUP_NOT_EXIST) {
				switch (creatures[i]) {
				case HUMAN:
					parseCreaturesTileData(i, "Creatures/Human/"
							+ defaultColor[i] + ".png");
					parseBuildingTileData(i, "Building/Human/"
							+ defaultColor[i] + ".png");
					break;
				case ELF:
					parseCreaturesTileData(i, "Creatures/Elf/"
							+ defaultColor[i] + ".png");
					parseBuildingTileData(i, "Building/Elf/" + defaultColor[i]
							+ ".png");
					break;
				}
			}
		}
		Texture buildingSheet = new Texture(
				Gdx.files.internal("Building/NEUTRAL.png"));
		TextureRegion[][] tmp = TextureRegion.split(buildingSheet, 64, 64);
		buildingTexture[DEFAULT_MAX_GROUP] = new TextureRegion[tmp[0].length
				* tmp.length];
		int index = 0;
		for (int l = 0; l < tmp.length; l++) {
			for (int j = 0; j < tmp[0].length; j++) {
				buildingTexture[DEFAULT_MAX_GROUP][index] = tmp[l][j];
				index++;
			}
		}
	}

	public void parseCreaturesTileData(int id, String texturePath) {
		Texture creaturesSheet = new Texture(Gdx.files.internal(texturePath));
		TextureRegion[][] tmp = TextureRegion.split(creaturesSheet, 64, 64);
		creatureTexture[id] = new TextureRegion[tmp[0].length * tmp.length];
		int index = 0;
		for (int l = 0; l < tmp.length; l++) {
			for (int j = 0; j < tmp[0].length; j++) {
				creatureTexture[id][index] = tmp[l][j];
				index++;
			}
		}
	}

	public void parseBuildingTileData(int id, String texturePath) {
		Texture buildingSheet = new Texture(Gdx.files.internal(texturePath));
		TextureRegion[][] tmp = TextureRegion.split(buildingSheet, 64, 64);
		buildingTexture[id] = new TextureRegion[tmp[0].length * tmp.length];
		int index = 0;
		for (int l = 0; l < tmp.length; l++) {
			for (int j = 0; j < tmp[0].length; j++) {
				buildingTexture[id][index] = tmp[l][j];
				index++;
			}
		}
	}
}
